﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using Microsoft.TeamFoundation.Framework.Server;

namespace TfsRollUp.Core
{
    /// <summary>
    /// Global settings for the service
    /// </summary>
    [Serializable()]
    public class Settings : INotifyPropertyChanged
    {
        private bool _enableRollUpProcessing;
        private HashSet<int> _workItemMonitorList;

        [NonSerialized]
        private TeamFoundationRequestContext _requestContext;

        /// <summary>
        /// Eventhandler for settings changes
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// The link to workitems in Tswa
        /// </summary>
        public string TswaLink { get; set; }

        private void SaveSettings(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            var rs = _requestContext.GetService<TeamFoundationRegistryService>();
            rs.SetValue(_requestContext, "/" + Constants.TfsRollUpPlugin + "/Settings", this.ToString());
        }

        /// <summary>
        /// Create the OnPropertyChanged method to raise the event
        /// </summary>
        /// <param name="name"></param>
        protected void OnPropertyChanged(string name)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(name));
            }
        }

        /// <summary>
        /// ctor
        /// </summary>
        public Settings(TeamFoundationRequestContext requestContext)
        {
            if (requestContext == null)
            {
                throw new ArgumentNullException("requestContext");
            }
            _requestContext = requestContext;
            _workItemMonitorList = new HashSet<int>();
            var locationService = _requestContext.GetService<TeamFoundationLocationService>();
            this.TswaLink = locationService.PublicAccessMapping.AccessPoint + "/web/UI/Pages/WorkItems/WorkItemEdit.aspx?id={0}";
            PropertyChanged += new PropertyChangedEventHandler(SaveSettings);
            _enableRollUpProcessing = true;
        }

        /// <summary>
        /// Enable or disable the processing of workitems
        /// </summary>
        public bool EnableRollUpProcesing
        {
            get { return _enableRollUpProcessing; }
            set
            {
                if (_enableRollUpProcessing != value)
                {
                    _enableRollUpProcessing = value;
                    OnPropertyChanged("EnableRollUpProcessing");
                }
            }
        }

        /// <summary>
        /// Add or remove workitem from monitor list
        /// </summary>
        /// <param name="workItemId"></param>
        /// <param name="enable"></param>
        /// <returns></returns>
        public int AddWorkItemToMonitorList(int workItemId, bool enable)
        {
            if (workItemId <= 0)
            {
                throw new ArgumentOutOfRangeException("workItemId");
            }

            if (enable && !_workItemMonitorList.Contains(workItemId))
            {
                _workItemMonitorList.Add(workItemId);
                OnPropertyChanged("EnableRollUpProcessing");
            }
            else if (!enable && _workItemMonitorList.Contains(workItemId))
            {
                _workItemMonitorList.Remove(workItemId);
                OnPropertyChanged("EnableRollUpProcessing");
            }
            return _workItemMonitorList.Count;
        }

        /// <summary>
        /// Is workitem in monitor list
        /// </summary>
        /// <param name="workItemId"></param>
        /// <returns></returns>
        public bool IsWorkItemOnMonitorList(int workItemId)
        {
            if (workItemId <= 0)
            {
                throw new ArgumentOutOfRangeException("workItemId");
            }
            return _workItemMonitorList.Contains(workItemId);
        }

        /// <summary>
        /// Very simple typeconversion/serialisation
        /// </summary>
        /// <param name="requestContext"></param>
        /// <returns></returns>
        public static Settings FromString(TeamFoundationRequestContext requestContext)
        {
            if (requestContext == null)
            {
                throw new ArgumentNullException("requestContext");
            }
            var settings = new Settings(requestContext);
            var rs = requestContext.GetService<TeamFoundationRegistryService>();
            var settingsString = rs.GetValue(requestContext, "/" + Constants.TfsRollUpPlugin + "/Settings");
            if (!string.IsNullOrWhiteSpace(settingsString))
            {
                var parts = settingsString.Split(',');
                bool.TryParse(parts[0], out settings._enableRollUpProcessing);
                for (int i = 2; i < parts.Length; i++)
                {
                    if (!string.IsNullOrWhiteSpace(parts[i]))
                    {
                        settings._workItemMonitorList.Add(int.Parse(parts[i]));
                    }
                }
            }
            return settings;
        }

        /// <summary>
        /// Very simple typeconversion/serialisation
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return string.Format("{0},{1},{2}", _enableRollUpProcessing, TswaLink, string.Join(",", _workItemMonitorList));
        }
    }
}
